// src/services/websocket.service.ts
class KefuWebSocketService {
    // WebSocket实例，用于与服务器建立连接
    private socket: WebSocket | null = null;

    // 当前用户的ID，用于标识连接的用户
    private userId: string = '';

    // 连接状态标识，true表示已连接，false表示未连接
    private isConnected: boolean = false;

    // 消息回调函数映射表，用于存储不同事件类型的处理函数
    private messageCallbacks: Map<string, (data: any) => void> = new Map();

    // 重连尝试次数计数器
    private reconnectAttempts: number = 0;

    // 最大重连尝试次数，超过此次数将不再自动重连
    private maxReconnectAttempts: number = 5;

    // 重连间隔时间（毫秒），每次重连前等待的时间
    private reconnectInterval: number = 3000;

    /**
     * 连接到WebSocket服务器
     * @param userId 用户ID
     * @returns Promise<boolean> 连接成功返回true，失败返回false
     */
    connect(userId: string): Promise<boolean> {
        // 返回一个Promise，用于异步处理连接结果
        return new Promise((resolve, reject) => {
            // 设置当前用户的ID
            this.userId = userId;

            // 构建WebSocket连接URL，包含用户ID作为路径参数
            const wsUrl = `ws://localhost:8088/api/websocket/${userId}`;

            try {
                // 创建WebSocket连接实例
                this.socket = new WebSocket(wsUrl);

                // 连接成功时的回调函数
                this.socket.onopen = (event: Event) => {
                    console.log(`WebSocket连接已建立，用户ID: ${userId}`);
                    // 更新连接状态
                    this.isConnected = true;
                    // 重置重连尝试次数
                    this.reconnectAttempts = 0;
                    // 触发连接成功消息回调
                    this.handleMessage('connect', { type: 'connect', message: '连接成功' });
                    // 解析Promise，表示连接成功
                    resolve(true);
                };

                // 接收消息时的回调函数
                this.socket.onmessage = (event: MessageEvent) => {
                    try {
                        // 获取消息数据
                        const message = event.data;
                        console.log(`收到消息: ${message}`);
                        // 处理接收到的消息
                        this.handleMessage('message', message);
                    } catch (error) {
                        // 消息处理出错时记录错误日志
                        console.error('处理消息时发生错误:', error);
                    }
                };

                // 连接关闭时的回调函数
                this.socket.onclose = (event: CloseEvent) => {
                    console.log(`WebSocket连接已关闭，用户ID: ${userId}，代码: ${event.code}`);
                    // 更新连接状态为断开
                    this.isConnected = false;

                    // 尝试重连逻辑
                    if (this.reconnectAttempts < this.maxReconnectAttempts) {
                        // 如果重连次数未达到最大限制，则尝试重连
                        this.reconnect();
                    } else {
                        // 达到最大重连次数后触发断开连接回调
                        this.handleMessage('disconnect', {
                            type: 'disconnect',
                            message: '连接已断开',
                            code: event.code
                        });
                    }
                };

                // 连接出错时的回调函数
                this.socket.onerror = (event: Event) => {
                    console.error(`WebSocket连接错误:`, event);
                    // 触发错误消息回调
                    this.handleMessage('error', { type: 'error', event });
                    // 拒绝Promise，传递错误信息
                    reject(event);
                };
            } catch (error) {
                // 创建WebSocket连接时发生异常，记录错误并拒绝Promise
                console.error('创建WebSocket连接时发生错误:', error);
                reject(error);
            }
        });
    }

    /**
     * 发送消息
     * @param message 要发送的消息内容
     * @returns boolean 发送成功返回true，失败返回false
     */
    sendMessage(message: string): boolean {
        if (!this.socket || !this.isConnected) {
            console.error('WebSocket未连接，无法发送消息');
            return false;
        }

        try {
            this.socket.send(message);
            console.log(`发送消息: ${message}`);
            return true;
        } catch (error) {
            console.error('发送消息时发生错误:', error);
            return false;
        }
    }

    /**
     * 发送私聊消息
     * @param targetUserId 目标用户ID
     * @param content 消息内容
     * @returns boolean 发送成功返回true，失败返回false
     */
    sendPrivateMessage(targetUserId: number | string, content: string): boolean {
        const message = `${targetUserId}:${content}`;
        return this.sendMessage(message);
    }

    sendMessageInKefu(targetUserId: number | string, shopId: number | string ,content: string): boolean {
        const message = `${targetUserId}:${shopId}:${content}`;
        return this.sendMessage(message);
    }
    /**
     * 发送广播消息
     * @param content 消息内容
     * @returns boolean 发送成功返回true，失败返回false
     */
    sendBroadcastMessage(content: string): boolean {
        const message = `broadcast:${content}`;
        return this.sendMessage(message);
    }

    /**
     * 注册消息回调
     * @param event 事件类型
     * @param callback 回调函数
     */
    on(event: string, callback: (data: any) => void): void {
        this.messageCallbacks.set(event, callback);
    }

    /**
     * 移除消息回调
     * @param event 事件类型
     */
    off(event: string): void {
        this.messageCallbacks.delete(event);
    }

    /**
     * 处理消息分发
     * @param event 事件类型
     * @param data 消息数据
     */
    private handleMessage(event: string, data: any): void {
        const callback = this.messageCallbacks.get(event);
        if (callback) {
            callback(data);
        }

        // 触发通用消息回调
        const generalCallback = this.messageCallbacks.get('message');
        if (generalCallback && event !== 'message') {
            generalCallback({ event, data });
        }
    }

    /**
     * 断开连接
     */
    disconnect(): void {
        if (this.socket) {
            this.socket.close();
            this.socket = null;
            this.isConnected = false;
        }
    }

    /**
     * 重连
     */
    private reconnect(): void {
        setTimeout(() => {
            this.reconnectAttempts++;
            console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);
            this.connect(this.userId).catch(err => {
                console.error(`重连失败:`, err);
            });
        }, this.reconnectInterval);
    }

    /**
     * 获取连接状态
     * @returns boolean 当前连接状态
     */
    get connected(): boolean {
        return this.isConnected;
    }

    /**
     * 获取在线用户列表（需要后端支持）
     * @returns Promise<any[]> 在线用户列表
     */
    getOnlineUsers(): Promise<any[]> {
        return new Promise((resolve) => {
            // 这里可以通过发送特定消息请求在线用户列表
            // 或者通过HTTP API获取
            resolve([]);
        });
    }
}

// 导出单例实例
export default new KefuWebSocketService();
